#include "dinput.h"
#include "..\engine\engine.h"
#include "..\common\def.h"

CDInput9Device::CDInput9Device()
{


	m_pDInput = NULL; 
	m_pKeyboardDevice = NULL; 
	m_pMouseDevice = NULL; 
	m_mouseWheel = 0; 
	m_State = UNINITALIZED; 

	memset(m_keyMap, 0, sizeof(m_keyMap)); 
	memset(m_prevKeyMap, 0, sizeof(m_prevKeyMap)); 
	memset(&m_mousePos, 0, sizeof(m_mousePos)); 
	memset(&m_mouseDelta, 0, sizeof(m_mouseDelta)); 
	memset(m_mouseBut, 0, sizeof(m_mouseBut)); 
	memset(m_mouseDataBuffer, 0, sizeof(m_mouseDataBuffer)); 
}

CDInput9Device::~CDInput9Device(void)
{
	memset(m_keyMap, 0, sizeof(m_keyMap)); 
	memset(m_prevKeyMap, 0, sizeof(m_prevKeyMap)); 
	memset(&m_mousePos, 0, sizeof(m_mousePos)); 
	memset(&m_mouseDelta, 0, sizeof(m_mouseDelta)); 
	memset(m_mouseBut, 0, sizeof(m_mouseBut)); 
	memset(m_mouseDataBuffer, 0, sizeof(m_mouseDataBuffer)); 

	m_pMouseDevice = NULL; 
	m_pKeyboardDevice = NULL; 
	m_pDInput = NULL; 
}

HRESULT CDInput9Device::CreateDevices()
{
	return (SUCCEEDED(CreateMouseDevice()) && SUCCEEDED(CreateKeyboardDevice())); 
}

HRESULT CDInput9Device::ReleaseDevices(void)
{
	return (SUCCEEDED(ReleaseMouseDevice()) && SUCCEEDED(ReleaseKeyboardDevice())); 
}

HRESULT CDInput9Device::Initailize()
{
	try{
		CLog::WriteLine("Creating Direct Input device"); 

		if(!ISNULL(m_pDInput))
			throw EE_EXCEPTION("No Direct Input device"); 
		
		if(ISNULL(CEngine::GetInstance()->GetWindow()->GethInstance()))
			throw EE_EXCEPTION("Invalid window instance"); 

		if(FAILED(DirectInput8Create(CEngine::GetInstance()->GetWindow()->GethInstance(), DIRECTINPUT_VERSION, IID_IDirectInput8, (void **) &m_pDInput, NULL)))
			throw EE_EXCEPTION("Failed to Create Direct Input device"); 
	
		CreateDevices(); 

		m_State = OK; 
		CLog::WriteLine("Success"); 
		return S_OK; 
	}
	catch(CError)
	{
		m_State = FAILED; 
		CLog::WriteLine("Failed"); 
		return E_FAIL; 
	}
}

HRESULT CDInput9Device::Release(void)
{
	try
	{
		CLog::Write("Releasing DirectX Input device\t\t"); 

		if(ISNULL(m_pDInput))
			throw EE_EXCEPTION("No Direct Input device")

		ReleaseDevices(); 

		if(FAILED(m_pDInput->Release()))
			throw EE_EXCEPTION("Failed to Release Direct Input device"); 

		m_State = OK; 
		m_pDInput = NULL; 
		CLog::WriteLine("OK"); 
		return S_OK; 
	}
	catch(CError)
	{
		m_State = FAILED; 
		CLog::WriteLine("DirectX Input device was not correctly released"); 
		return E_FAIL; 
	}
}

HRESULT CDInput9Device::Update(void)
{
	switch(m_State)
	{
	case DeviceState::OK:
			{
				if(GetFocus() != CEngine::GetInstance()->GetWindow()->GetHWnd())
					m_State = LOST_FOCUS; 
				else
				{
					if(FAILED(UpdateMouse()))
						m_State = FAILED; 
					if(FAILED(UpdateKeyboard()))
						m_State = FAILED; 
				}
			}break; 

	case DeviceState::LOST_FOCUS:
			{
				if(GetFocus() == CEngine::GetInstance()->GetWindow()->GetHWnd())
					m_State = OK; 
			}break; 

	case DeviceState::FAILED:
			{
				CLog::Write("DirectX Input device runtime error\n"); 
				ResetMouseState(); 
				ResetKeyboardState(); 
				m_State = (FAILED(CreateDevices())) ? UNINITALIZED : OK; 
				return E_FAIL; 
			}break; 

	case DeviceState::UNINITALIZED:
			{
				return E_FAIL; 
			}break; 
	}

	return S_OK; 
}
